<!-- BaseMessage.vue -->
<script setup lang="ts">
import { computed, ref } from 'vue'
import { NAvatar, NIcon, NInput, NImage } from 'naive-ui'
import { Download } from '@vicons/tabler'
import type { Message } from './type'

const props = withDefaults(
  defineProps<{
    message: Message
    loading?: boolean
    type: 'text' | 'image' | 'file'
    placement: 'left' | 'right'
    avatarColor?: string
    avatarText?: string
    bgColor?: string
    editable?: boolean
  }>(),
  {
    loading: false
  }
)

const isEditing = ref(false)
const editedContent = ref('')

const getAvatarColor = computed(
  () => props.avatarColor || (props.message.sender === 'user' ? '#1890ff' : '#52c41a')
)

const getBgColor = computed(
  () => props.bgColor || (props.message.sender === 'user' ? 'bg-blue-100' : 'bg-gray-100')
)

const getAvatarText = computed(
  () => props.avatarText || (props.message.sender === 'user' ? 'U' : 'B')
)

const flexDirection = computed(() =>
  props.placement === 'right' ? 'flex-row-reverse' : 'flex-row'
)

const textAlignment = computed(() => (props.placement === 'right' ? 'text-right' : 'text-left'))
</script>

<template>
  <div :class="['text-sm text-gray-500 mb-1', textAlignment]">
    <slot name="header">{{
      message.sender.charAt(0).toUpperCase() + message.sender.slice(1)
    }}</slot>
  </div>
  <div :class="['flex', flexDirection]">
    <NAvatar :style="{ backgroundColor: getAvatarColor }">{{ getAvatarText }}</NAvatar>
    <div
      :class="['ml-2 mr-2 relative group']"
      style="min-width: 300px; min-height: 60px; max-width: 70%"
    >
      <div v-if="loading" class="flex items-center p-15px pl-30px">
        <div class="loader"></div>
      </div>
      <template v-else>
        <div
          v-if="!isEditing"
          class="text text-gray-800 p-3 rounded-lg break-words whitespace-pre-wrap"
          :class="[getBgColor, 'message-content']"
        >
          <template v-if="type === 'text'">
            {{ message.content }}
          </template>
          <NImage
            v-else-if="type === 'image'"
            :src="message.imageUrl"
            :width="300"
            object-fit="cover"
          />
          <div v-else-if="type === 'file'" class="flex items-center">
            <NIcon :component="Download" class="mr-2" />
            <span>{{ message.fileName }} ({{ message.fileSize }} bytes)</span>
          </div>
        </div>
        <NInput
          v-else
          v-model:value="editedContent"
          type="textarea"
          :autosize="{ minRows: 1, maxRows: 5 }"
        />
        <div
          class="opacity-0 transition-opacity duration-200 group-hover:opacity-100 flex justify-between items-center"
        >
          <span class="text-gray-500 text-xs items-end flex">{{
            new Date(message.timestamp).toLocaleString()
          }}</span>
          <div class="flex space-x-1 mt-1 gap-10px">
            <slot name="actions"></slot>
          </div>
        </div>
      </template>
    </div>
  </div>
</template>

<style scoped>
.loader {
  width: 5px;
  aspect-ratio: 1;
  border-radius: 50%;
  animation: l5 1s infinite linear alternate;
}
@keyframes l5 {
  0% {
    box-shadow:
      15px 0 #000,
      -15px 0 #0002;
    background: #000;
  }
  33% {
    box-shadow:
      15px 0 #000,
      -15px 0 #0002;
    background: #0002;
  }
  66% {
    box-shadow:
      15px 0 #0002,
      -15px 0 #000;
    background: #0002;
  }
  100% {
    box-shadow:
      15px 0 #0002,
      -15px 0 #000;
    background: #000;
  }
}
</style>
